<!doctype html>
<html>
	<head>
		<title>Synthetic events with real data store must inherit protection status from real events</title>
		<style type="text/css">
blockquote { height: 100px; width: 100px; background: orange; margin: 0; padding: 0; float: left; }
blockquote + blockquote { background: blue; }
blockquote + blockquote + blockquote { background: fuchsia; }
blockquote + div { clear: left; }
		</style>
		<script type="text/javascript" src="/resources/testharness.js"></script>
		<script type="text/javascript">
setup(function () {},{explicit_done:true,explicit_timeout:true});
window.onload = function () {

	var orange  = document.getElementsByTagName('blockquote')[0],
	    blue    = document.getElementsByTagName('blockquote')[1],
	    fuchsia = document.getElementsByTagName('blockquote')[2],
	    evtdone = {};

	orange.ondragstart = function (e) {
		evtdone[e.type] = true;
		e.dataTransfer.effectAllowed = 'copy';

		var t = async_test(e.type+' should share its data with the synthetic event');
		blue.ondragstart = function (e) {
			t.step(function() {
				assert_equals( e.dataTransfer.getData('text'), 'dragstart real data', 'step 1' );
				e.dataTransfer.setData('text','dragstart-dragstart synthetic data');
				assert_equals( e.dataTransfer.getData('text'), 'dragstart-dragstart synthetic data', 'step 2' );
			});
		};
		t.step(function() {
			var evt = new DragEvent('dragstart', {dataTransfer:e.dataTransfer});
			e.dataTransfer.setData('text','dragstart real data'); //changing in between steps, just to make sure it uses the underlying data store, not a temporary clone
			blue.dispatchEvent(evt);
		});
		t.done();

		test(function() {
			assert_equals( e.dataTransfer.getData('text'), 'dragstart-dragstart synthetic data' );
		}, e.type+' should see the data from the synthetic event' );

		var t2 = async_test(e.type+' should share its protection status with the synthetic event');
		blue.ondrag = function (e) {
			t2.step(function() {
				e.dataTransfer.setData('text','dragstart-drag synthetic data');
				assert_equals( e.dataTransfer.getData('text'), 'dragstart-drag synthetic data' );
			});
		};
		t2.step(function() {
			var evt = new DragEvent('drag', {dataTransfer:e.dataTransfer});
			blue.dispatchEvent(evt);
		});
		t2.done();

		var t3 = async_test(e.type+' should share its protection status with the nested synthetic event');
		blue.ondrag = function (e) {
			blue.ondragend = function (e) {
				t3.step(function() {
					assert_equals( e.dataTransfer.getData('text'), 'dragstart-drag synthetic data', 'step1' );
					e.dataTransfer.setData('text','dragstart-drag-dragend synthetic data');
					assert_equals( e.dataTransfer.getData('text'), 'dragstart-drag-dragend synthetic data', 'step2' );
				});
			};
			t3.step(function() {
				var evt = new DragEvent('dragend', {dataTransfer:e.dataTransfer});
				blue.dispatchEvent(evt);
			});
		};
		t3.step(function() {
			var evt = new DragEvent('drag', {dataTransfer:e.dataTransfer});
			blue.dispatchEvent(evt);
		});
		t3.done();

		test(function() {
			assert_equals( e.dataTransfer.getData('text'), 'dragstart-drag-dragend synthetic data' );
		}, e.type+' should see the data from the nested synthetic event' );
	};

	blue.ondragenter = blue.ondragover = function (e) {
		e.preventDefault();
	};
	orange.ondrag = blue.ondragleave = function (e) {
		if( evtdone[e.type] ) { return; }
		evtdone[e.type] = true;
		var evtype = e.type;

		var t = async_test(e.type+' should share its data with the synthetic event');
		blue.ondragstart = function (e) {
			t.step(function() {
				assert_true( e.dataTransfer.items.length > 0, 'items.length' );
			});
		};
		t.step(function() {
   var evt = new DragEvent('dragstart', {dataTransfer:e.dataTransfer});
			blue.dispatchEvent(evt);
		});
		t.done();

		var t2 = async_test(e.type+' should share its protection status with the synthetic event');
		blue.ondragstart = function (e) {
			t2.step(function() {
				assert_equals( e.dataTransfer.getData('text'), '', 'step 1' );
				e.dataTransfer.setData('text',evtype+'-dragstart synthetic data');
				assert_equals( e.dataTransfer.getData('text'), '', 'step 2' );
			});
		};
		t2.step(function() {
   var evt = new DragEvent('dragstart', {dataTransfer:e.dataTransfer});
			blue.dispatchEvent(evt);
		});
		t2.done();

		test(function() {
			assert_equals( e.dataTransfer.getData('text'), '' );
		}, e.type+' protection status should not be modified by the synthetic event' );

		var t3 = async_test(e.type+' should share its protection status with the nested synthetic event');
		blue.ondragstart = function (e) {
			var div = document.createElement('div');
			div.ondragstart = function (e) {
				t3.step(function() {
					assert_equals( e.dataTransfer.getData('text'), '', 'step1' );
					e.dataTransfer.setData('text',evtype+'dragstart-dragstart synthetic data');
					assert_equals( e.dataTransfer.getData('text'), '', 'step2' );
				});
			};
			t3.step(function() {
   var evt = new DragEvent('dragend', {dataTransfer:e.dataTransfer});
				div.dispatchEvent(evt);
			});
		};
		t3.step(function() {
   var evt = new DragEvent('drag', {dataTransfer:e.dataTransfer});
			blue.dispatchEvent(evt);
		});
		t3.done();
	};

	fuchsia.ondragenter = fuchsia.ondragover = function (e) {
		e.preventDefault();
		if( evtdone[e.type] ) { return; }
		evtdone[e.type] = true;
		var evtype = e.type;

		var t = async_test(e.type+' should share its data with the synthetic event');
		blue.ondragstart = function (e) {
			t.step(function() {
				assert_true( e.dataTransfer.items.length > 0, 'items.length' );
			});
		};
		t.step(function() {
   var evt = new DragEvent('dragstart', {dataTransfer:e.dataTransfer});
			blue.dispatchEvent(evt);
		});
		t.done();

		var t2 = async_test(e.type+' should share its protection status with the synthetic event');
		blue.ondragstart = function (e) {
			t2.step(function() {
				assert_equals( e.dataTransfer.getData('text'), '', 'step 1' );
				e.dataTransfer.setData('text',evtype+'-dragstart synthetic data');
				assert_equals( e.dataTransfer.getData('text'), '', 'step 2' );
			});
		};
		t2.step(function() {
   var evt = new DragEvent('dragstart', {dataTransfer:e.dataTransfer});
			blue.dispatchEvent(evt);
		});
		t2.done();

		test(function() {
			assert_equals( e.dataTransfer.getData('text'), '' );
		}, e.type+' protection status should not be modified by the synthetic event' );

		var t3 = async_test(e.type+' should share its protection status with the nested synthetic event');
		blue.ondragstart = function (e) {
			var div = document.createElement('div');
			div.ondragstart = function (e) {
				t3.step(function() {
					assert_equals( e.dataTransfer.getData('text'), '', 'step1' );
					e.dataTransfer.setData('text',evtype+'dragstart-dragstart synthetic data');
					assert_equals( e.dataTransfer.getData('text'), '', 'step2' );
				});
			};
			t3.step(function() {
    var evt = new DragEvent('dragend', {dataTransfer:e.dataTransfer});
				div.dispatchEvent(evt);
			});
		};
		t3.step(function() {
   var evt = new DragEvent('drag', {dataTransfer:e.dataTransfer});
			blue.dispatchEvent(evt);
		});
		t3.done();
	};

	fuchsia.ondrop = function (e) {
		e.preventDefault();
		if( evtdone[e.type] ) { return; }
		evtdone[e.type] = true;
		var evtype = e.type;

		var t = async_test(e.type+' should share its data with the synthetic event');
		blue.ondragstart = function (e) {
			t.step(function() {
				assert_equals( e.dataTransfer.getData('text'), 'dragstart-drag-dragend synthetic data' );
			});
		};
		t.step(function() {
   var evt = new DragEvent('dragstart', {dataTransfer:e.dataTransfer});
			blue.dispatchEvent(evt);
		});
		t.done();

		var t2 = async_test(e.type+' should share its protection status with the synthetic event');
		blue.ondragstart = function (e) {
			t2.step(function() {
				assert_equals( e.dataTransfer.getData('text'), 'dragstart-drag-dragend synthetic data', 'step 1' );
				e.dataTransfer.setData('text',evtype+'-dragstart synthetic data');
				assert_equals( e.dataTransfer.getData('text'), 'dragstart-drag-dragend synthetic data', 'step 2' );
			});
		};
		t2.step(function() {
   var evt = new DragEvent('dragstart', {dataTransfer:e.dataTransfer});
			blue.dispatchEvent(evt);
		});
		t2.done();

		test(function() {
			e.dataTransfer.setData('text','drop synthetic data');
			assert_equals( e.dataTransfer.getData('text'), 'dragstart-drag-dragend synthetic data' );
		}, e.type+' protection status should not be modified by the synthetic event' );

		var t3 = async_test(e.type+' should share its protection status with the nested synthetic event');
		blue.ondragstart = function (e) {
			var div = document.createElement('div');
			div.ondragstart = function (e) {
				t3.step(function() {
					assert_equals( e.dataTransfer.getData('text'), 'dragstart-drag-dragend synthetic data', 'step 1' );
					e.dataTransfer.setData('text',evtype+'dragstart-dragstart synthetic data');
					assert_equals( e.dataTransfer.getData('text'), 'dragstart-drag-dragend synthetic data', 'step 2' );
				});
			};
			t3.step(function() {
   var evt = new DragEvent('dragend', {dataTransfer:e.dataTransfer});
				div.dispatchEvent(evt);
			});
		};
		t3.step(function() {
   var evt = new DragEvent('drag', {dataTransfer:e.dataTransfer});
			blue.dispatchEvent(evt);
		});
		t3.done();
	};

	orange.ondragend = function (e) {
		if( evtdone[e.type] ) { return; }
		evtdone[e.type] = true;
		var evtype = e.type;

		var t = async_test(e.type+' should share its data with the synthetic event');
		blue.ondragstart = function (e) {
			t.step(function() {
				assert_true( e.dataTransfer.items.length > 0, 'items.length' );
			});
		};
		t.step(function() {
   var evt = new DragEvent('dragstart', {dataTransfer:e.dataTransfer});
			blue.dispatchEvent(evt);
		});
		t.done();

		var t2 = async_test(e.type+' should share its protection status with the synthetic event');
		blue.ondragstart = function (e) {
			t2.step(function() {
				assert_equals( e.dataTransfer.getData('text'), '', 'step 1' );
				e.dataTransfer.setData('text',evtype+'-dragstart synthetic data');
				assert_equals( e.dataTransfer.getData('text'), '', 'step 2' );
			});
		};
		t2.step(function() {
   var evt = new DragEvent('dragstart', {dataTransfer:e.dataTransfer});
			blue.dispatchEvent(evt);
		});
		t2.done();

		test(function() {
			assert_equals( e.dataTransfer.getData('text'), '' );
		}, e.type+' protection status should not be modified by the synthetic event' );

		var t3 = async_test(e.type+' should share its protection status with the nested synthetic event');
		blue.ondragstart = function (e) {
			var div = document.createElement('div');
			div.ondragstart = function (e) {
				t3.step(function() {
					assert_equals( e.dataTransfer.getData('text'), '', 'step1' );
					e.dataTransfer.setData('text',evtype+'dragstart-dragstart synthetic data');
					assert_equals( e.dataTransfer.getData('text'), '', 'step2' );
				});
			};
			t3.step(function() {
   var evt = new DragEvent('dragend', {dataTransfer:e.dataTransfer});
				div.dispatchEvent(evt);
			});
		};
		t3.step(function() {
   var evt = new DragEvent('drag', {dataTransfer:e.dataTransfer});
			blue.dispatchEvent(evt);
		});
		t3.done();

		test(function() {
			var failtxt = '- Reload and try again';
			assert_true( evtdone.dragstart, 'dragstart event was not tested'+failtxt );
			assert_true( evtdone.drag, 'drag event was not tested'+failtxt );
			assert_true( evtdone.dragenter, 'dragenter event was not tested'+failtxt );
			assert_true( evtdone.dragleave, 'dragleave event was not tested'+failtxt );
			assert_true( evtdone.dragover, 'dragover event was not tested'+failtxt );
			assert_true( evtdone.drop, 'drop event was not tested'+failtxt );
			assert_true( evtdone.dragend, 'dragend event was not tested'+failtxt );
		}, 'all event types must now have been tested' );
		done();
	};

};
		</script>
	</head>
	<body>
		<p>Drag the orange square over the blue square then the fuchsia square, then release it.</p>
		<blockquote draggable="true"></blockquote>
		<blockquote></blockquote>
		<blockquote></blockquote>
		<div id="log"></div>
		<noscript><p>Enable JavaScript and reload</p></noscript>
	</body>
</html>